/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package managedbean;

import entity.AnalyticsEntity;

import entity.BranchEntity;
import entity.ChosenMetricEntity;

import entity.MetricTypeEntity;

import entity.PackagePurchasedEntity;
import entity.ServicePackageEntity;

import entity.StakeholderEntity;
import entity.TCubeEntity;
import java.io.IOException;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.PhaseEvent;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.DashboardColumn;
import org.primefaces.model.DashboardModel;
import org.primefaces.model.DefaultDashboardColumn;
import org.primefaces.model.DefaultDashboardModel;
import session.stateful.MetricSessionBean;

import util.entityhelper.MonthHelper;
import org.primefaces.component.chart.series.ChartSeries;
import org.primefaces.model.chart.CartesianChartModel;
import java.util.Collections;
import javax.faces.model.SelectItem;
import org.primefaces.component.commandbutton.CommandButton;
import org.primefaces.component.panel.Panel;
import org.primefaces.event.CloseEvent;
import session.stateful.StakeholderSessionBeanStateful;
import util.entityhelper.DoubleComparator;
import util.entityhelper.DoubleHelper;
import util.entityhelper.MetricHelper;
import util.entityhelper.PositionComparator;
import util.entityhelper.SpecialType;

/**
 *
 * @author Nguyen Cong Dat
 */
@ManagedBean(name = "tCubeMetricManagerBean")
@SessionScoped
public class TCubeMetricManagerBean implements Serializable {

    @EJB
    private MetricSessionBean metricSessionbean;
    @EJB
    private StakeholderSessionBeanStateful stakeholderSessionBean;
    /*
     * 
     */
    private boolean initPage;
    private List<DashboardModel> dashboardList;
    private Map<Long, MetricHelper> metricMap;
    private Map<Long, Integer> typeMap;
    private List<MetricTypeEntity> listOfType;
    private int select;
    private DashboardModel selectedDashboard;
    private TCubeEntity tCube;
    /*
     * 
     */
    private DashboardModel model;
    private List<String> result;
    private HashMap<Long, Double> bestUsers = new HashMap<Long, Double>();
    private List entrySet_branch;
    private List entrySet_stakeholder;
    private int rank;
    private MonthHelper selectedMonth;
    private FacesContext ctx = FacesContext.getCurrentInstance();

    /** Creates a new instance of BasicMetricManagerBean */
    public TCubeMetricManagerBean() {
        metricMap = new HashMap<Long, MetricHelper>();
        dashboardList = new ArrayList<DashboardModel>();
        typeMap = new HashMap<Long, Integer>();
        initPage = true;
    }

    public void saveCustomizedList(ActionEvent event) {
        DashboardModel board = getDashboardList().get(0);

        metricSessionbean.saveTCubeCustomizedList(tCube.getId(), board.getColumn(0).getWidgets(), board.getColumn(1).getWidgets());
    }

    public void removeMetricFromList(CloseEvent event) throws IOException {
        System.out.println("Remove");
        System.out.println(event.getSource().getClass());
        Panel panel = (Panel) event.getSource();
        String name = panel.getId();

        removeMetricFromDashboard(getSelect(), name);

        long id = Long.valueOf(name.substring(1));
        int pos = getTypeMap().get(id);

        addMetricToDashboard(pos, name);
        System.out.println("Finish removing");
             String serverName = ctx.getExternalContext().getRequestServerName();
            int serverPort = (Integer) ctx.getExternalContext().getSessionMap().get("serverPort");
            String contextPath = ctx.getExternalContext().getRequestContextPath();
            ctx.getExternalContext().redirect("http://" + serverName + ":" + serverPort + contextPath + "/staff/TCubeAnalytics.xhtml");
    }

    public void addMetricToList(ActionEvent event) throws IOException {
        CommandButton button = (CommandButton) event.getSource();

        System.out.println("Compute Now!");
        String name = button.getId().substring(1);
        System.out.println("Add to list");
        removeMetricFromDashboard(getSelect(), name);
        addMetricToDashboard(0, name);
        System.out.println("Finish adding");

                     String serverName = ctx.getExternalContext().getRequestServerName();
            int serverPort = (Integer) ctx.getExternalContext().getSessionMap().get("serverPort");
            String contextPath = ctx.getExternalContext().getRequestContextPath();
            ctx.getExternalContext().redirect("http://" + serverName + ":" + serverPort + contextPath + "/staff/TCubeAnalytics.xhtml");
    }

    private void removeMetricFromDashboard(int dashPos, String metricName) {
        DashboardModel board = getDashboardList().get(dashPos);
        for (DashboardColumn c : board.getColumns()) {
            if (c.getWidgets().contains(metricName)) {
                c.removeWidget(metricName);
                break;
            }
        }
    }

    private void addMetricToDashboard(int dashPos, String metricName) {
        DashboardModel board = getDashboardList().get(dashPos);
        DashboardColumn column1 = board.getColumn(0);
        DashboardColumn column2 = board.getColumn(1);
        if (column1.getWidgetCount() <= column2.getWidgetCount()) {
            column1.addWidget(metricName);
        } else {
            column2.addWidget(metricName);
        }
    }

    /*
     * This method is used to initiate everything for analytics website. Must be used in another
     * webpage rather than the TCubeAnalytics.xhtml
     */
    public void initAnalytics(PhaseEvent event) {
        System.out.println(1);
        //only load this once
        if (initPage) {
            DashboardModel board = new DefaultDashboardModel();
            System.out.println(2);
            tCube = (TCubeEntity) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("TCube");
            System.out.println("TCUBE ID " + tCube.getId());
            //get list of metric chosen by this stakeholder
            List<ChosenMetricEntity> listOfChosenMetric = metricSessionbean.getListOfChosenMetricByTCubeId(tCube.getId());
            //get all metrics available
            setListOfType(metricSessionbean.getAllMetricType());

            //sort the list according to position of chosen metric in the displayed dashboard
            Collections.sort(listOfChosenMetric, new PositionComparator());
            DashboardColumn column1 = new DefaultDashboardColumn();
            DashboardColumn column2 = new DefaultDashboardColumn();
            //Divide chosen metric into the columns
            for (ChosenMetricEntity m : listOfChosenMetric) {
                if (m.getColumnPosition() == 0) {
                    column1.addWidget("a" + m.getAnalytics().getId());
                } else {
                    column2.addWidget("a" + m.getAnalytics().getId());
                }
                createMetricHelper(m.getAnalytics());
            }

            //each dashboard will have two columns
            board.addColumn(column1);
            board.addColumn(column2);
            //this one is for customized metric as it will be in index 0 of the list
            getDashboardList().add(board);

            //each metric type will have their corresponding dashboard
            for (int i = 0; i < getListOfType().size(); i++) {
                //get all analytics of this type
                List<AnalyticsEntity> listOfAnalytics = metricSessionbean.getAnalyticsByTypeForTCube(getListOfType().get(i).getId());
                System.out.println("Size of list for tucbe " + listOfAnalytics.size());
                //create two new columns for this new dashboard
                column1 = new DefaultDashboardColumn();
                column2 = new DefaultDashboardColumn();
                //go through each analytics in this list
                for (AnalyticsEntity ana : listOfAnalytics) {
                    System.out.println(3);
                    getTypeMap().put(ana.getId(), i + 1);
                    boolean chosen = false;
                    //check whether this one is already in customized list
                    for (ChosenMetricEntity temp : listOfChosenMetric) {
                        if (temp.getAnalytics().equals(ana)) {
                            chosen = true;
                            break;
                        }
                    }
                    System.out.println(4);
                    //if not then add this one in this dashboard
                    if (!chosen) {
                        System.out.println("4a");
                        if (column1.getWidgetCount() <= column2.getWidgetCount()) {
                            //create a new id for this Widget because the system
                            //doesn't accept id by number only
                            column1.addWidget("a" + ana.getId());
                        } else {
                            column2.addWidget("a" + ana.getId());
                        }
                        System.out.println("4b");
                        createMetricHelper(ana);
                    }
                    System.out.println(5);
                }

                //refresh the dashboard and add these two columns into it
                board = new DefaultDashboardModel();
                board.addColumn(column1);
                board.addColumn(column2);
                System.out.println(6);
                //put it in the list of dashboard
                getDashboardList().add(board);
            }

            //put the customized list at the beginning of the list of dashboard
            //and list of type
            MetricTypeEntity customized = new MetricTypeEntity();
            customized.setName("Customized");
            getListOfType().add(0, customized);

            initList(0);
            setSelectedDashboard(getDashboardList().get(0));

            //we only load this once
            initPage = false;
        }
    }
    /*
     * Purpose: Change to corresponding dashboard when the user click on the list
     * of metric type on the left hand side
     */

    public void changeMetricType(SelectEvent event) throws IOException {
        System.out.println("change metric type");

        //check the position of this metric type in the list of metric type
        MetricTypeEntity type = (MetricTypeEntity) event.getObject();
        int pos = 0;
        for (; pos < getListOfType().size(); pos++) {
            if (type.getName().equals(getListOfType().get(pos).getName())) {
                break;
            }
        }
        System.out.println(pos);
        //change the selected position to this position
        setSelect(pos);
        //retrieve the corresponding dashboard
        setSelectedDashboard(getDashboardList().get(pos));
        //try to init all the metrics inside it
        initList(getSelect());
        FacesContext.getCurrentInstance().getExternalContext().redirect("staff/TCubeAnalytics.xhtml");
    }

    private void createMetricHelper(AnalyticsEntity ana) {
        System.out.println("metric helper");
        MetricHelper metric = new MetricHelper(ana);
        System.out.println("metric map");
        getMetricMap().put(ana.getId(), metric);
    }

    public MetricHelper getMetricMap(String name) {
        long id = Long.valueOf(name.substring(1));
        return getMetricMap().get(id);
    }

    /*
     * Purpose: init all the metrics inside this dashboard
     */
    private void initList(int pos) {
        System.out.println("init List");
        DashboardModel model = getDashboardList().get(pos);
        System.out.println("abc");
        for (int i = 0; i < 2; i++) {
            DashboardColumn column1 = model.getColumn(i);
            for (String widget : column1.getWidgets()) {
                initMetric(widget);
            }
        }
    }

    /*
     * Purpose: init this metric. Based on the id of the metric, we
     * must have corresponding method to init it
     */
    private void initMetric(String name) {
        long id = Long.valueOf(name.substring(1));
        System.out.println("init Metric " + name);
        for (long i = 100; i <= 108; i++) {
            if (id == i) {
                initSelectMonth(id);
            }
        }

        if (id == 109) {
            initProfitableSubscriber(id);
        }

        if (id == 110 || id == 111 || id == 112) {
            initGrowth(id);
        }
    }
    // Added by Cong Dat

    public void initSelectMonth(long id) {
        System.out.println("Select Month");
        MetricHelper metric = metricMap.get(id);

        if (!metric.isInit()) {
            metric.setCompute(true);
            List list = new ArrayList<SelectItem>();


            String[] month = MonthHelper.getStringMonth();

            int startMonth = 9;
            int startYear = 2011;
            Date date = new Date();
            int currentMonth = date.getMonth() + 1;
            int currentYear = date.getYear() + 1900;

            while (startMonth != currentMonth || startYear != currentYear) {
                list.add(new SelectItem(startYear * 100 + startMonth, month[startMonth - 1] + " " + startYear));
                startMonth = (startMonth + 1) % 12;
                if (startMonth == 0) {
                    startYear++;
                }
            }
            metric.addSelectList(list, "Month and year");

            metric.setInit(true);
        }
    }

    public void initGrowth(long id) {
        MetricHelper metric = metricMap.get(id);
        if (!metric.isInit()) {
            metric.setCompute(true);
            metric.addDateList("From");
            metric.addDateList("To");

            List<SelectItem> list = new ArrayList<SelectItem>();
            list.add(new SelectItem(0, "Day"));
            list.add(new SelectItem(1, "Week"));
            list.add(new SelectItem(2, "Month"));

            metric.addSelectList(list, "Type");
            metric.setInit(true);
            metric.setCompute(true);
        }
    }

    public void compute(ActionEvent event) throws IOException {
        CommandButton button = (CommandButton) event.getSource();

        System.out.println("Compute Now!");
        long id = Long.valueOf(button.getId().substring(2));
        if (id == 100) {
            computeTotalRevenue(id);
        }
        if (id == 101) {
            computeTotalCostForULP(id);
        }

        if (id == 102) {
            computeNumberOfRewardingULPPoint(id);
        }

        if (id == 103) {
            computeNumberOfStaffAccount(id);
        }

        if (id == 104) {
            computeNumberOfStakeholderAccount(id);
        }

        if (id == 105) {
            computeNumberOfTouristAccount(id);
        }

        if (id == 106) {
            computeNumberOfSubscriber(id);
        }

        if (id == 107) {
            computeAcquisitionRate(id);
        }

        if (id == 108) {
            computeMostPopularServicePackage(id);
        }

        if (id == 110) {
            computeAccountGrowth(id);
        }

        if (id == 111) {
            computeSubscriptionGrowth(id);
        }
            
        if (id == 112) {
            computeSaleGrowth(id);
        }
        FacesContext.getCurrentInstance().getExternalContext().redirect("staff/TCubeAnalytics.xhtml");
    }

    public void computeTotalRevenue(long id) {
        MetricHelper metric = metricMap.get(id);
        metric.resetOutputValue();
        int value = metric.getSelectVar();
        int month = value % 100;
        int year = value / 100;

        selectedMonth = new MonthHelper(month, year);
        String totalRevenue = metricSessionbean.getTotalTCubeRevenueByMonth(selectedMonth) + "";
        metric.addOutputValue("Total Revenue per month", totalRevenue);
    }

    public void computeNumberOfSubscriber(long id) {
        MetricHelper metric = metricMap.get(id);
        metric.resetOutputValue();
        int value = metric.getSelectVar();
        int month = value % 100;
        int year = value / 100;

        selectedMonth = new MonthHelper(month, year);
        String numberOfSubscribers = metricSessionbean.getNumberOfSubscribersByMonth(selectedMonth) + "";
        metric.addOutputValue("Number of subscriber", numberOfSubscribers);
    }

    public void computeTotalCostForULP(long id) {
        MetricHelper metric = metricMap.get(id);
        metric.resetOutputValue();
        int value = metric.getSelectVar();
        int month = value % 100;
        int year = value / 100;

        selectedMonth = new MonthHelper(month, year);
        String totalCostForULP = metricSessionbean.getTotalCostOfULPByMonth(selectedMonth) + "";
        metric.addOutputValue("Total cost of ULP per month", totalCostForULP);
    }

    public void computeNumberOfStakeholderAccount(long id) {
        MetricHelper metric = metricMap.get(id);
        metric.resetOutputValue();
        int value = metric.getSelectVar();
        int month = value % 100;
        int year = value / 100;

        selectedMonth = new MonthHelper(month, year);
        int numberOfActiveStakeholderAccounts = metricSessionbean.getNumberOfActiveStakeholders(selectedMonth);
        int numberOfInactiveStakeholderAccounts = metricSessionbean.getNumberOfInactiveStakeholders(selectedMonth);
        int total = numberOfActiveStakeholderAccounts + numberOfInactiveStakeholderAccounts;
        metric.addOutputValue("Total", total + "");
        metric.addOutputValue("Activate", numberOfActiveStakeholderAccounts + "");
        metric.addOutputValue("Inactivate", numberOfInactiveStakeholderAccounts + "");
    }

    public void computeNumberOfTouristAccount(long id) {
        System.out.println("Compute Number of Tourist Account");
        MetricHelper metric = metricMap.get(id);
        metric.resetOutputValue();
        int value = metric.getSelectVar();
        int month = value % 100;
        int year = value / 100;

        selectedMonth = new MonthHelper(month, year);
        String numberOfTouristAccount = metricSessionbean.getNumberOfTouristAccounts(selectedMonth) + "";
        metric.addOutputValue("Number of Tourist Account ", numberOfTouristAccount);
    }

    public void computeNumberOfStaffAccount(long id) {
        MetricHelper metric = metricMap.get(id);
        metric.resetOutputValue();
        int value = metric.getSelectVar();
        int month = value % 100;
        int year = value / 100;

        selectedMonth = new MonthHelper(month, year);
        String numberOfStaffAccount = metricSessionbean.getNumberOfStaffAccounts(selectedMonth) + "";
        metric.addOutputValue("Total staffs ", numberOfStaffAccount);
    }

    public void computeNumberOfRewardingULPPoint(long id) {
        MetricHelper metric = metricMap.get(id);
        metric.resetOutputValue();
        int value = metric.getSelectVar();
        int month = value % 100;
        int year = value / 100;

        selectedMonth = new MonthHelper(month, year);
        String numberOfRewardingULPPoint = metricSessionbean.getRewardingULPPointsByMonth(selectedMonth) + "";
        metric.addOutputValue("Total ULP points awarded", numberOfRewardingULPPoint);
    }

    public void computeAcquisitionRate(long id) {
        MetricHelper metric = metricMap.get(id);
        metric.resetOutputValue();
        int value = metric.getSelectVar();
        int month = value % 100;
        int year = value / 100;

        selectedMonth = new MonthHelper(month, year);
        int stakeholderTemp = metricSessionbean.getNumberOfActiveStakeholders(selectedMonth) + metricSessionbean.getNumberOfInactiveStakeholders(selectedMonth);
        int subscriber = metricSessionbean.getNumberOfSubscribersByMonth(selectedMonth);
        double acquisition = 0;

        if (stakeholderTemp != 0) {
            acquisition = (double) subscriber / stakeholderTemp;
        }
        metric.addOutputValue("Acquisition Rate", acquisition + "");
    }

    public void computeMostPopularServicePackage(long id) {
        MetricHelper metric = metricMap.get(id);
        metric.resetDataTable();
        int value = metric.getSelectVar();
        int month = value % 100;
        int year = value / 100;

        selectedMonth = new MonthHelper(month, year);
        List<DoubleHelper> resultList = metricSessionbean.getMostLeastPopularServicePackageByMonth(selectedMonth);

        List<SpecialType> list = new ArrayList<SpecialType>();
        SpecialType type = new SpecialType();
        type.addValue("Name");
        type.addValue("Price");
        type.addValue("Subscribers");
        list.add(type);

        for (DoubleHelper helper : resultList) {
            ServicePackageEntity s = (ServicePackageEntity) helper.getObject();
            type = new SpecialType();
            type.addValue(s.getName());
            type.addValue(s.getPrice() + "");
            double num = helper.getDoubleNum();
            int temp = (int) num;
            type.addValue(temp + "");
            list.add(type);
        }

        metric.addDataTable(list, "Popular Service Package");
    }

    //Most profitable subsriber-start
    public void initProfitableSubscriber(long id) {
        MetricHelper metric = metricMap.get(id);
        if (!metric.isInit()) {
            List<StakeholderEntity> stakeholderList = new ArrayList<StakeholderEntity>();
            List<DoubleHelper> list = new ArrayList<DoubleHelper>();

            stakeholderList = stakeholderSessionBean.getAllStakeholders();
            for (StakeholderEntity s : stakeholderList) {
                Double contractValue = 0.0;
                List<BranchEntity> branchList = s.getBranches();

                for (BranchEntity b : branchList) {
                    List<PackagePurchasedEntity> packagePurchasedList = new ArrayList<PackagePurchasedEntity>();
                    packagePurchasedList = b.getPackagePurchased();

                    for (PackagePurchasedEntity p : packagePurchasedList) {
                        int timeInterval;

                        timeInterval = p.getDateExpired().getMonth() - p.getDatePurchased().getMonth()
                                + (p.getDateExpired().getYear() - p.getDatePurchased().getYear()) * 12;
                        contractValue += p.getPrice() * timeInterval;
                    }
                }
                list.add(new DoubleHelper(s, contractValue));
            }
            Collections.sort(list, new DoubleComparator());
            List<SpecialType> table = new ArrayList<SpecialType>();
            SpecialType type = new SpecialType();
            type.addValue("Id");
            type.addValue("Corp Name");
            type.addValue("Contract Value");
            table.add(type);

            for (DoubleHelper helper : list) {
                StakeholderEntity s = (StakeholderEntity) helper.getObject();
                type = new SpecialType();
                type.addValue(s.getId() + "");
                type.addValue(s.getCorpName());
                type.addValue(helper.getDoubleNum() + "");
                table.add(type);
            }
            metric.addDataTable(table, "Top subscribers");
            metric.setInit(true);
        }
    }
    //Most profitable subsriber-end  

    public void computeAccountGrowth(long id) {
        MetricHelper metric = metricMap.get(id);
        System.out.println("compute account growth");
        int currentValue = metric.getSelectVar();

        //0 for day, 1 for week, 2 for month

        CartesianChartModel accountGrowthLine = new CartesianChartModel();

        ChartSeries touristAccountGrowth = new ChartSeries();
        ChartSeries stakeholderAccountGrowth = new ChartSeries();

        touristAccountGrowth.setLabel("Number of Tourist Accounts");
        stakeholderAccountGrowth.setLabel("Number of Stakeholder Accounts");

        Date start = new Date(metric.getDateList().getTime());
        Date end = metric.getDateList();

        while (start.compareTo(end) <= 0) {
            SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");

            touristAccountGrowth.set(sdf.format(start), metricSessionbean.getNumberOfTouristAccountsByDate(start));
            stakeholderAccountGrowth.set(sdf.format(start), metricSessionbean.getNumberOfStakeholderAccountsByDate(start));
            if (currentValue == 0) {
                start.setTime(start.getTime() + 1 * 24 * 60 * 60 * 1000);
            } else if (currentValue == 1) {
                start.setTime(start.getTime() + 7 * 24 * 60 * 60 * 1000);
            } else if (currentValue == 2) {
                start = addMonthsToCurrentDate(start, 1);
            }
        }
        accountGrowthLine.addSeries(touristAccountGrowth);
        accountGrowthLine.addSeries(stakeholderAccountGrowth);
        metric.setModel(accountGrowthLine);
        System.out.println("End method");
    }

    public void computeSubscriptionGrowth(long id) {
        MetricHelper metric = metricMap.get(id);
        System.out.println("compute subscription growth");
        System.out.println(metric.getChartType());
        int currentValue = metric.getSelectVar();
        System.out.println("value now " + currentValue);
        CartesianChartModel subscriptionGrowthLine = new CartesianChartModel();
        ChartSeries subscriptionGrowth = new ChartSeries();
        subscriptionGrowth.setLabel("Number of subscriptions");

        Date start = new Date(metric.getDateList().getTime());
        Date end = metric.getDateList();

        while (start.compareTo(end) <= 0) {
            SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
            if (currentValue == 0) {
                System.out.println("type 0");
                subscriptionGrowth.set(sdf.format(start), metricSessionbean.getNumberOfSubscribersByDate(start));
                start.setTime(start.getTime() + 1 * 24 * 60 * 60 * 1000);
            } else if (currentValue == 1) {
                System.out.println("type 1");
                Date temp = start;
                start.setTime(start.getTime() - 7 * 24 * 60 * 60 * 1000);
                subscriptionGrowth.set(sdf.format(temp), metricSessionbean.getNumberOfSubscribersByPeriod(temp, start));
                start.setTime(start.getTime() + 14 * 24 * 60 * 60 * 1000);
            } else {
                System.out.println("type 2");
                int month = start.getMonth() + 1;
                int year = start.getYear() + 1900;
                MonthHelper temp = new MonthHelper(month, year);
                subscriptionGrowth.set(temp.getText(), metricSessionbean.getNumberOfSubscribersByMonth(temp));
                start = addMonthsToCurrentDate(start, 1);
            }
        }
        System.out.println("end of method");
        subscriptionGrowthLine.addSeries(subscriptionGrowth);
        metric.setModel(subscriptionGrowthLine);
    }

    public void computeSaleGrowth(long id) {
        MetricHelper metric = metricMap.get(id);

        int currentValue = metric.getSelectVar();
        CartesianChartModel totalSaleGrowthLine = new CartesianChartModel();
        ChartSeries totalSaleGrowth = new ChartSeries();
        totalSaleGrowth.setLabel("Total Sale Growth");
        
        Date start = new Date(metric.getDateList().getTime());
        Date end = metric.getDateList();

        while (start.compareTo(end) <= 0) {
            SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
            if (currentValue == 0) {
                totalSaleGrowth.set(sdf.format(start), metricSessionbean.getTotalSalesByDate(start));
                start.setTime(start.getTime() + 1 * 24 * 60 * 60 * 1000);
            } else if (currentValue == 1) {
                Date temp = start;
                start.setTime(start.getTime() - 7 * 24 * 60 * 60 * 1000);
                totalSaleGrowth.set(sdf.format(temp), metricSessionbean.getTotalSalesByPeriod(temp, start));
                start.setTime(start.getTime() + 14 * 24 * 60 * 60 * 1000);
            } else {
                int month = start.getMonth() + 1;
                int year = start.getYear() + 1900;
                MonthHelper temp = new MonthHelper(month, year);

                totalSaleGrowth.set(temp.getText(), metricSessionbean.getTotalSalesByMonth(temp));
                start = addMonthsToCurrentDate(start, 1);
            }
        }

        totalSaleGrowthLine.addSeries(totalSaleGrowth);
        metric.setModel(totalSaleGrowthLine);
    }
    /*
    public void calculateGrowthByDay(ActionEvent event) throws IOException {
    accountGrowthLine = new CartesianChartModel();
    subscriptionGrowthLine = new CartesianChartModel();
    totalSaleGrowthLine = new CartesianChartModel();
    
    ChartSeries touristAccountGrowth = new ChartSeries();
    ChartSeries stakeholderAccountGrowth = new ChartSeries();
    ChartSeries subscriptionGrowth = new ChartSeries();
    ChartSeries totalSaleGrowth = new ChartSeries();
    
    touristAccountGrowth.setLabel("Number of Tourist Accounts");
    stakeholderAccountGrowth.setLabel("Number of Stakeholder Accounts");
    subscriptionGrowth.setLabel("Number of subscriptions");
    totalSaleGrowth.setLabel("Total Sale Growth");
    
    Date start = startDate;
    Date end = endDate;
    //
    while (start.compareTo(end) <= 0) {
    SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
    touristAccountGrowth.set(sdf.format(start), metricSessionbean.getNumberOfTouristAccountsByDate(start));
    stakeholderAccountGrowth.set(sdf.format(start), metricSessionbean.getNumberOfStakeholderAccountsByDate(start));
    subscriptionGrowth.set(sdf.format(start), metricSessionbean.getNumberOfSubscribersByDate(start));
    totalSaleGrowth.set(sdf.format(start), metricSessionbean.getTotalSalesByDate(start));
    start.setTime(start.getTime() + 1 * 24 * 60 * 60 * 1000);
    }
    getAccountGrowthLine().addSeries(touristAccountGrowth);
    getAccountGrowthLine().addSeries(stakeholderAccountGrowth);
    getSubscriptionGrowthLine().addSeries(subscriptionGrowth);
    totalSaleGrowthLine.addSeries(totalSaleGrowth);
    FacesContext.getCurrentInstance().getExternalContext().redirect("TCubeViewGrowth.xhtml");
    }
     * */

    /*
    public void calculateGrowthByWeek(ActionEvent event) throws IOException {
    accountGrowthLine = new CartesianChartModel();
    subscriptionGrowthLine = new CartesianChartModel();
    totalSaleGrowthLine = new CartesianChartModel();
    
    ChartSeries touristAccountGrowth = new ChartSeries();
    ChartSeries stakeholderAccountGrowth = new ChartSeries();
    ChartSeries subscriptionGrowth = new ChartSeries();
    ChartSeries totalSaleGrowth = new ChartSeries();
    
    touristAccountGrowth.setLabel("Number of Tourist Accounts");
    stakeholderAccountGrowth.setLabel("Number of Stakeholder Accounts");
    subscriptionGrowth.setLabel("Number of subscriptions");
    totalSaleGrowth.setLabel("Total Sale Growth");
    
    Date start = startDate;
    Date end = endDate;
    
    //
    while (start.compareTo(end) <= 0) {
    SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
    touristAccountGrowth.set(sdf.format(start), metricSessionbean.getNumberOfTouristAccountsByDate(start));
    stakeholderAccountGrowth.set(sdf.format(start), metricSessionbean.getNumberOfStakeholderAccountsByDate(start));
    Date temp = start;
    start.setTime(start.getTime() - 7 * 24 * 60 * 60 * 1000);
    subscriptionGrowth.set(sdf.format(temp), metricSessionbean.getNumberOfSubscribersByPeriod(temp, start));
    totalSaleGrowth.set(sdf.format(temp), metricSessionbean.getTotalSalesByPeriod(temp, start));
    start.setTime(start.getTime() + 14 * 24 * 60 * 60 * 1000);
    }
    getAccountGrowthLine().addSeries(touristAccountGrowth);
    getAccountGrowthLine().addSeries(stakeholderAccountGrowth);
    getSubscriptionGrowthLine().addSeries(subscriptionGrowth);
    totalSaleGrowthLine.addSeries(totalSaleGrowth);
    
    FacesContext.getCurrentInstance().getExternalContext().redirect("TCubeViewGrowth.xhtml");
    }
     * */
    /*
    public void calculateGrowthByMonth(ActionEvent event) throws IOException {
    accountGrowthLine = new CartesianChartModel();
    subscriptionGrowthLine = new CartesianChartModel();
    totalSaleGrowthLine = new CartesianChartModel();
    
    ChartSeries touristAccountGrowth = new ChartSeries();
    ChartSeries stakeholderAccountGrowth = new ChartSeries();
    ChartSeries subscriptionGrowth = new ChartSeries();
    ChartSeries totalSaleGrowth = new ChartSeries();
    
    touristAccountGrowth.setLabel("Number of Tourist Accounts");
    stakeholderAccountGrowth.setLabel("Number of Stakeholder Accounts");
    subscriptionGrowth.setLabel("Number of subscriptions");
    totalSaleGrowth.setLabel("Total Sale Growth");
    
    Date start = startDate;
    Date end = endDate;
    
    while (start.compareTo(end) <= 0) {
    int month = start.getMonth() + 1;
    int year = start.getYear() + 1900;
    MonthHelper temp = new MonthHelper(month, year);
    SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
    touristAccountGrowth.set(sdf.format(start), metricSessionbean.getNumberOfTouristAccountsByDate(start));
    stakeholderAccountGrowth.set(sdf.format(start), metricSessionbean.getNumberOfStakeholderAccountsByDate(start));
    subscriptionGrowth.set(temp.getText(), metricSessionbean.getNumberOfSubscribersByMonth(temp));
    totalSaleGrowth.set(temp.getText(), metricSessionbean.getTotalSalesByMonth(temp));
    start = addMonthsToCurrentDate(start, 1);
    }
    getAccountGrowthLine().addSeries(touristAccountGrowth);
    getAccountGrowthLine().addSeries(stakeholderAccountGrowth);
    getSubscriptionGrowthLine().addSeries(subscriptionGrowth);
    totalSaleGrowthLine.addSeries(totalSaleGrowth);
    
    FacesContext.getCurrentInstance().getExternalContext().redirect("TCubeViewGrowth.xhtml");
    }
     * */
    // Add months to a current date
    public Date addMonthsToCurrentDate(Date currentDate, int numberOfMonths) {
        //create Calendar instance
        Calendar cal = Calendar.getInstance();
        cal.setTime(currentDate);
        cal.add(Calendar.MONTH, numberOfMonths);
        return cal.getTime();
    }

    public List getEntrySet_branch() {
        return entrySet_branch;
    }

    public void setEntrySet_branch(List entrySet_branch) {
        this.entrySet_branch = entrySet_branch;
    }

    public List getEntrySet_stakeholder() {
        return entrySet_stakeholder;
    }

    public void setEntrySet_stakeholder(List entrySet_stakeholder) {
        this.entrySet_stakeholder = entrySet_stakeholder;
    }

    public int getRank() {
        return rank;
    }

    public void setRank(int rank) {
        this.rank = rank;
    }

    public MonthHelper getSelectedMonth() {
        return selectedMonth;
    }

    public void setSelectedMonth(MonthHelper selectedMonth) {
        this.selectedMonth = selectedMonth;
    }

    public List<DashboardModel> getDashboardList() {
        return dashboardList;
    }

    public void setDashboardList(List<DashboardModel> dashboardList) {
        this.dashboardList = dashboardList;
    }

    public Map<Long, MetricHelper> getMetricMap() {
        return metricMap;
    }

    public void setMetricMap(Map<Long, MetricHelper> metricMap) {
        this.metricMap = metricMap;
    }

    public Map<Long, Integer> getTypeMap() {
        return typeMap;
    }

    public void setTypeMap(Map<Long, Integer> typeMap) {
        this.typeMap = typeMap;
    }

    public List<MetricTypeEntity> getListOfType() {
        return listOfType;
    }

    public void setListOfType(List<MetricTypeEntity> listOfType) {
        this.listOfType = listOfType;
    }

    public int getSelect() {
        return select;
    }

    public void setSelect(int select) {
        this.select = select;
    }

    public DashboardModel getSelectedDashboard() {
        return selectedDashboard;
    }

    public void setSelectedDashboard(DashboardModel selectedDashboard) {
        this.selectedDashboard = selectedDashboard;
    }

    class ValueComparator implements Comparator {

        Map base;

        public ValueComparator(Map base) {
            this.base = base;
        }

        @Override
        public int compare(Object a, Object b) {

            if ((Double) base.get(a) < (Double) base.get(b)) {
                return 1;
            } else if ((Double) base.get(a) == (Double) base.get(b)) {
                return 0;
            } else {
                return -1;
            }
        }
    }

    class ValueComparatorInt implements Comparator {

        Map base;

        public ValueComparatorInt(Map base) {
            this.base = base;
        }

        @Override
        public int compare(Object a, Object b) {

            if ((Integer) base.get(a) < (Integer) base.get(b)) {
                return 1;
            } else if ((Integer) base.get(a) == (Integer) base.get(b)) {
                return 0;
            } else {
                return -1;
            }
        }
    }

    public MetricSessionBean getBasicMetricSessionBean() {
        return metricSessionbean;
    }

    public void setBasicMetricSessionBean(MetricSessionBean metricSessionbean) {
        this.metricSessionbean = metricSessionbean;
    }

    public DashboardModel getModel() {
        return model;
    }

    public void setModel(DashboardModel model) {
        this.model = model;
    }

    public HashMap<Long, Double> getBestUsers() {
        return bestUsers;
    }

    public void setBestUsers(HashMap<Long, Double> bestUsers) {
        this.bestUsers = bestUsers;
    }
}
